/*
 *
 *  Copyright (C) 2001-2011, OFFIS e.V.
 *  All rights reserved.  See COPYRIGHT file for details.
 *
 *  This software and supporting documentation were developed by
 *
 *    OFFIS e.V.
 *    R&D Division Health
 *    Escherweg 2
 *    D-26121 Oldenburg, Germany
 *
 *
 *  Module:  dcmjp2
 *
 *  Author:  qinwl,2017.06.27
 *
 *  Purpose: abstract codec class for JPEG decoders.
 *
 */

#ifndef DJP2CODECD_H
#define DJP2CODECD_H

#include "dcmtk/config/osconfig.h"
#include "dcmtk/ofstd/oftypes.h"
#include "dcmtk/dcmdata/dccodec.h"    /* for class DcmCodec */
#include "dcmtk/ofstd/ofstring.h"   /* for class OFString */
#include "dcmtk/dcmjp2/djp2define.h"

/** decoder class for J2K.
*  This class only supports decompression, it neither implements
*  encoding nor transcoding.
*/
class DCMTK_DCMJP2_EXPORT DcmJ2KCodecDecoder : public DcmCodec
{
public:

	/// default constructor
	DcmJ2KCodecDecoder();

	/// destructor
	virtual ~DcmJ2KCodecDecoder();

	/** decompresses the given pixel sequence and
	*  stores the result in the given uncompressedPixelData element.
	*  @param fromRepParam current representation parameter of compressed data, may be NULL
	*  @param pixSeq compressed pixel sequence
	*  @param uncompressedPixelData uncompressed pixel data stored in this element
	*  @param cp codec parameters for this codec
	*  @param objStack stack pointing to the location of the pixel data
	*    element in the current dataset.
	*  @return EC_Normal if successful, an error code otherwise.
	*/
	virtual OFCondition decode(
		const DcmRepresentationParameter * fromRepParam,
		DcmPixelSequence * pixSeq,
		DcmPolymorphOBOW& uncompressedPixelData,
		const DcmCodecParameter * cp,
		const DcmStack& objStack) const;

	/** decompresses a single frame from the given pixel sequence and
	*  stores the result in the given buffer.
	*  @param fromParam representation parameter of current compressed
	*    representation, may be NULL.
	*  @param fromPixSeq compressed pixel sequence
	*  @param cp codec parameters for this codec
	*  @param dataset pointer to dataset in which pixel data element is contained
	*  @param frameNo number of frame, starting with 0 for the first frame
	*  @param startFragment index of the compressed fragment that contains
	*    all or the first part of the compressed bitstream for the given frameNo.
	*    Upon successful return this parameter is updated to contain the index
	*    of the first compressed fragment of the next frame.
	*    When unknown, zero should be passed. In this case the decompression
	*    algorithm will try to determine the index by itself, which will always
	*    work if frames are decompressed in increasing order from first to last,
	*    but may fail if frames are decompressed in random order, multiple fragments
	*    per frame and multiple frames are present in the dataset, and the offset
	*    table is empty.
	*  @param buffer pointer to buffer where frame is to be stored
	*  @param bufSize size of buffer in bytes
	*  @param decompressedColorModel upon successful return, the color model
	*    of the decompressed image (which may be different from the one used
	*    in the compressed images) is returned in this parameter.
	*  @return EC_Normal if successful, an error code otherwise.
	*/
	virtual OFCondition decodeFrame(
		const DcmRepresentationParameter * fromParam,
		DcmPixelSequence * fromPixSeq,
		const DcmCodecParameter * cp,
		DcmItem *dataset,
		Uint32 frameNo,
		Uint32& startFragment,
		void *buffer,
		Uint32 bufSize,
		OFString& decompressedColorModel) const;

	/** compresses the given uncompressed DICOM image and stores
	*  the result in the given pixSeq element.
	*  @param pixelData pointer to the uncompressed image data in OW format
	*    and local byte order
	*  @param length of the pixel data field in bytes
	*  @param toRepParam representation parameter describing the desired
	*    compressed representation (e.g. JPEG quality)
	*  @param pixSeq compressed pixel sequence (pointer to new DcmPixelSequence object
	*    allocated on heap) returned in this parameter upon success.
	*  @param cp codec parameters for this codec
	*  @param objStack stack pointing to the location of the pixel data
	*    element in the current dataset.
	*  @return EC_Normal if successful, an error code otherwise.
	*/
	virtual OFCondition encode(
		const Uint16 * pixelData,
		const Uint32 length,
		const DcmRepresentationParameter * toRepParam,
		DcmPixelSequence * & pixSeq,
		const DcmCodecParameter *cp,
		DcmStack & objStack) const;

	/** transcodes (re-compresses) the given compressed DICOM image and stores
	*  the result in the given toPixSeq element.
	*  @param fromRepType current transfer syntax of the compressed image
	*  @param fromRepParam current representation parameter of compressed data, may be NULL
	*  @param fromPixSeq compressed pixel sequence
	*  @param toRepParam representation parameter describing the desired
	*    new compressed representation (e.g. JPEG quality)
	*  @param toPixSeq compressed pixel sequence (pointer to new DcmPixelSequence object
	*    allocated on heap) returned in this parameter upon success.
	*  @param cp codec parameters for this codec
	*  @param objStack stack pointing to the location of the pixel data
	*    element in the current dataset.
	*  @return EC_Normal if successful, an error code otherwise.
	*/
	virtual OFCondition encode(
		const E_TransferSyntax fromRepType,
		const DcmRepresentationParameter * fromRepParam,
		DcmPixelSequence * fromPixSeq,
		const DcmRepresentationParameter * toRepParam,
		DcmPixelSequence * & toPixSeq,
		const DcmCodecParameter * cp,
		DcmStack & objStack) const;

	/** checks if this codec is able to convert from the
	*  given current transfer syntax to the given new
	*  transfer syntax
	*  @param oldRepType current transfer syntax
	*  @param newRepType desired new transfer syntax
	*  @return true if transformation is supported by this codec, false otherwise.
	*/
	virtual OFBool canChangeCoding(
		const E_TransferSyntax oldRepType,
		const E_TransferSyntax newRepType) const;

	/** determine color model of the decompressed image
	*  @param fromParam representation parameter of current compressed
	*    representation, may be NULL
	*  @param fromPixSeq compressed pixel sequence
	*  @param cp codec parameters for this codec
	*  @param dataset pointer to dataset in which pixel data element is contained
	*  @param dataset pointer to DICOM dataset in which this pixel data object
	*    is located. Used to access photometric interpretation.
	*  @param decompressedColorModel upon successful return, the color model
	*    of the decompressed image (which may be different from the one used
	*    in the compressed images) is returned in this parameter
	*  @return EC_Normal if successful, an error code otherwise
	*/
	virtual OFCondition determineDecompressedColorModel(
		const DcmRepresentationParameter *fromParam,
		DcmPixelSequence *fromPixSeq,
		const DcmCodecParameter *cp,
		DcmItem *dataset,
		OFString &decompressedColorModel) const;

private:

	/// private undefined copy constructor
	DcmJ2KCodecDecoder(const DcmJ2KCodecDecoder&);

	/// private undefined copy assignment operator
	DcmJ2KCodecDecoder& operator=(const DcmJ2KCodecDecoder&);
};

#endif
